home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / citycon.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  7KB  |  296 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12.  
  13.  
  14. unsigned char *citycon_charlookup;
  15. unsigned char *citycon_scroll;
  16. static struct osd_bitmap *tmpbitmap2;
  17. static int bg_image,dirty_background;
  18. static unsigned char dirtylookup[32];
  19. static int flipscreen;
  20.  
  21.  
  22.  
  23. /***************************************************************************
  24.  
  25.   Start the video hardware emulation.
  26.  
  27. ***************************************************************************/
  28. int citycon_vh_start(void)
  29. {
  30.     if ((dirtybuffer = malloc(videoram_size)) == 0)
  31.         return 1;
  32.     memset(dirtybuffer,1,videoram_size);
  33.  
  34.     dirty_background = 1;
  35.  
  36.     /* CityConnection has a virtual screen 4 times as large as the visible screen */
  37.     if ((tmpbitmap = osd_new_bitmap(4 * Machine->drv->screen_width,Machine->drv->screen_height,Machine->scrbitmap->depth)) == 0)
  38.     {
  39.         free(dirtybuffer);
  40.         return 1;
  41.     }
  42.  
  43.     /* And another one for background */
  44.     if ((tmpbitmap2 = osd_new_bitmap(4 * Machine->drv->screen_width,Machine->drv->screen_height,Machine->scrbitmap->depth)) == 0)
  45.     {
  46.                 osd_free_bitmap(tmpbitmap);
  47.         free(dirtybuffer);
  48.         return 1;
  49.     }
  50.  
  51.     return 0;
  52. }
  53.  
  54.  
  55.  
  56. /***************************************************************************
  57.  
  58.   Stop the video hardware emulation.
  59.  
  60. ***************************************************************************/
  61. void citycon_vh_stop(void)
  62. {
  63.     free(dirtybuffer);
  64.     osd_free_bitmap(tmpbitmap);
  65.     osd_free_bitmap(tmpbitmap2);
  66. }
  67.  
  68.  
  69.  
  70. WRITE_HANDLER( citycon_charlookup_w )
  71. {
  72.     if (citycon_charlookup[offset] != data)
  73.     {
  74.         citycon_charlookup[offset] = data;
  75.  
  76.         dirtylookup[offset / 8] = 1;
  77.     }
  78. }
  79.  
  80.  
  81.  
  82. WRITE_HANDLER( citycon_background_w )
  83. {
  84.     /* bits 4-7 control the background image */
  85.     if (bg_image != (data >> 4))
  86.     {
  87.         bg_image = data >> 4;
  88.         dirty_background = 1;
  89.     }
  90.  
  91.     /* bit 0 flips screen */
  92.     /* it is also used to multiplex player 1 and player 2 controls */
  93.     if (flipscreen != (data & 1))
  94.     {
  95.         flipscreen = data & 1;
  96.         memset(dirtybuffer,1,videoram_size);
  97.         dirty_background = 1;
  98.     }
  99.  
  100.     /* bits 1-3 are unknown */
  101.     if ((data & 0x0e) != 0) logerror("background register = %02x\n",data);
  102. }
  103.  
  104. READ_HANDLER( citycon_in_r )
  105. {
  106.     return readinputport(flipscreen);
  107. }
  108.  
  109.  
  110. /***************************************************************************
  111.  
  112.   Draw the game screen in the given osd_bitmap.
  113.   Do NOT call osd_update_display() from this function, it will be called by
  114.   the main emulation engine.
  115.  
  116. ***************************************************************************/
  117. void citycon_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  118. {
  119.     int offs;
  120.  
  121.  
  122. palette_init_used_colors();
  123.  
  124. for (offs = videoram_size - 1;offs >= 0;offs--)
  125. {
  126.     int code,color;
  127.  
  128.     code = memory_region(REGION_GFX4)[0x1000 * bg_image + offs];
  129.     color = memory_region(REGION_GFX4)[0xc000 + 0x100 * bg_image + code],
  130.     memset(&palette_used_colors[256 + 16 * color],PALETTE_COLOR_USED,16);
  131. }
  132. for (offs = 0;offs < 256;offs++)
  133. {
  134.     int color;
  135.  
  136.     color = citycon_charlookup[offs];
  137.     palette_used_colors[512 + 4 * color] = PALETTE_COLOR_TRANSPARENT;
  138.     memset(&palette_used_colors[512 + 4 * color + 1],PALETTE_COLOR_USED,3);
  139. }
  140. for (offs = spriteram_size-4;offs >= 0;offs -= 4)
  141. {
  142.     int color;
  143.  
  144.     color = spriteram[offs + 2] & 0x0f;
  145.     memset(&palette_used_colors[16 * color + 1],PALETTE_COLOR_USED,15);
  146. }
  147.  
  148. if (palette_recalc())
  149. {
  150.     memset(dirtybuffer,1,videoram_size);
  151.     dirty_background = 1;
  152. }
  153.  
  154.  
  155.     /* Create the background */
  156.     if (dirty_background)
  157.     {
  158.         dirty_background = 0;
  159.  
  160.         for (offs = videoram_size - 1;offs >= 0;offs--)
  161.         {
  162.             int sx,sy,code;
  163.  
  164.  
  165.             sy = offs / 32;
  166.             sx = (offs % 32) + (sy & 0x60);
  167.             sy = sy & 31;
  168.             if (flipscreen)
  169.             {
  170.                 sx = 127 - sx;
  171.                 sy = 31 - sy;
  172.             }
  173.  
  174.             code = memory_region(REGION_GFX4)[0x1000 * bg_image + offs];
  175.  
  176.             drawgfx(tmpbitmap2,Machine->gfx[3 + bg_image],
  177.                     code,
  178.                     memory_region(REGION_GFX4)[0xc000 + 0x100 * bg_image + code],
  179.                     flipscreen,flipscreen,
  180.                     8*sx,8*sy,
  181.                     0,TRANSPARENCY_NONE,0);
  182.         }
  183.     }
  184.  
  185.     /* copy the temporary bitmap to the screen */
  186.     {
  187.         int scroll;
  188.  
  189.         if (flipscreen)
  190.             scroll = 256 + ((citycon_scroll[0]*256+citycon_scroll[1]) >> 1);
  191.         else
  192.             scroll = -((citycon_scroll[0]*256+citycon_scroll[1]) >> 1);
  193.  
  194.         copyscrollbitmap(bitmap,tmpbitmap2,1,&scroll,0,0,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  195.     }
  196.  
  197.  
  198.     /* for every character in the Video RAM, check if it has been modified */
  199.     /* since last time and update it accordingly. */
  200.     for (offs = videoram_size - 1;offs >= 0;offs--)
  201.     {
  202.         int sx,sy;
  203.  
  204.  
  205.         sy = offs / 32;
  206.         sx = (offs % 32) + (sy & 0x60);
  207.         sy = sy & 0x1f;
  208.  
  209.         if (dirtybuffer[offs] || dirtylookup[sy])
  210.         {
  211.             int i;
  212.             struct rectangle clip;
  213.  
  214.  
  215.             dirtybuffer[offs] = 0;
  216.  
  217.             if (flipscreen)
  218.             {
  219.                 sx = 127 - sx;
  220.                 sy = 31 - sy;
  221.             }
  222.             clip.min_x = 8*sx;
  223.             clip.max_x = 8*sx+7;
  224.  
  225.             /* City Connection controls the color code for each _scanline_, not */
  226.             /* for each character as happens in most games. Therefore, we have to draw */
  227.             /* the character eight times, each time clipped to one line and using */
  228.             /* the color code for that scanline */
  229.             for (i = 0;i < 8;i++)
  230.             {
  231.                 clip.min_y = 8*sy + i;
  232.                 clip.max_y = 8*sy + i;
  233.  
  234.                 drawgfx(tmpbitmap,Machine->gfx[0],
  235.                         videoram[offs],
  236.                         citycon_charlookup[flipscreen ? (255 - 8*sy - i) : 8*sy + i],
  237.                         flipscreen,flipscreen,
  238.                         8*sx,8*sy,
  239.                         &clip,TRANSPARENCY_NONE,0);
  240.             }
  241.         }
  242.     }
  243.  
  244.  
  245.     /* copy the temporary bitmap to the screen */
  246.     {
  247.         int i,scroll[32];
  248.  
  249.  
  250.         if (flipscreen)
  251.         {
  252.             for (i = 0;i < 6;i++)
  253.                 scroll[31-i] = 256;
  254.             for (i = 6;i < 32;i++)
  255.                 scroll[31-i] = 256 + (citycon_scroll[0]*256+citycon_scroll[1]);
  256.         }
  257.         else
  258.         {
  259.             for (i = 0;i < 6;i++)
  260.                 scroll[i] = 0;
  261.             for (i = 6;i < 32;i++)
  262.                 scroll[i] = -(citycon_scroll[0]*256+citycon_scroll[1]);
  263.         }
  264.         copyscrollbitmap(bitmap,tmpbitmap,32,scroll,0,0,
  265.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  266.     }
  267.  
  268.  
  269.     for (offs = spriteram_size-4;offs >= 0;offs -= 4)
  270.     {
  271.         int sx,sy,flipx;
  272.  
  273.  
  274.         sx = spriteram[offs + 3];
  275.         sy = 239 - spriteram[offs];
  276.         flipx = ~spriteram[offs + 2] & 0x10;
  277.         if (flipscreen)
  278.         {
  279.             sx = 240 - sx;
  280.             sy = 238 - sy;
  281.             flipx = !flipx;
  282.         }
  283.  
  284.         drawgfx(bitmap,Machine->gfx[spriteram[offs + 1] & 0x80 ? 2 : 1],
  285.                 spriteram[offs + 1] & 0x7f,
  286.                 spriteram[offs + 2] & 0x0f,
  287.                 flipx,flipscreen,
  288.                 sx,sy,
  289.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  290.     }
  291.  
  292.  
  293.     for (offs = 0;offs < 32;offs++)
  294.         dirtylookup[offs] = 0;
  295. }
  296.